<template>
  <div class="addChipContent">
    <el-drawer
      :with-header="false"
      :visible.sync="drawerVisible"
      size="800px"
      :close-on-press-escape="false"
      :wrapper-closable="false"
    >
      <div class="drawerForm">
        <div class="pageTitle">
          <div class="titleText">添加芯片</div>
        </div>
        <el-form
          ref="formData"
          class="myForm"
          :model="formData"
          label-width="138px"
          :rules="rules"
          label-suffix="："
        >
          <el-form-item label="芯片类型" prop="chipType">
            <el-select v-model="formData.chipType">
              <el-option label="主控芯片" :value="1"></el-option>
              <el-option label="被控芯片" :value="2"></el-option>
            </el-select>
            <el-button style="margin-left: 10px" type="primary" @click="handleDownLoad">下载示例模板</el-button>
          </el-form-item>
          <el-form-item label="芯片定义文件" prop="chipDefinitionFiles">
            <el-upload
              ref="chipDefinitionFiles"
              class="upload-demo"
              action="#"
              :limit="1"
              :file-list="formData.chipDefinitionFiles"
              :on-exceed="handleExceed"
              :accept="uploadSetting.fileAccept"
              :on-remove="() => handleRemove('chipDefinitionFiles')"
              :http-request="(require) => handleUploadFiles(require, 'chipDefinitionFiles')"
            >
              <div slot="tip" class="el-upload__tip">
                只能上传{{ uploadSetting.fileAccept.split(',').join(' ') }}文件，且单个文件不超过 20 MB
              </div>
              <el-button size="small" plain>
                上传文件
                <i class="el-icon-upload el-icon--right" />
              </el-button>
            </el-upload>
          </el-form-item>
          <el-form-item label="文件规则检查">
            <div class="percentageBox">
              <el-progress
                :percentage="fileRulesCheckPercentage"
                :status="getPercentageStatus(fileRulesCheckResult)"
                :show-text="false"
              ></el-progress>
              <template v-if="fileRulesCheckResult === 'fail'">
                <i class="el-icon-circle-close failResult" />
                <el-button type="primary" class="downloadBtn" @click="handleView">查看检查结果</el-button>
              </template>
              <i v-else-if="fileRulesCheckResult === 'success'" class="el-icon-circle-check successResult" />
            </div>
          </el-form-item>

          <el-form-item
            v-if="formData.chipType === 1 && startParameterConfigurationRuleGeneration"
            label="参数配置规则生成"
          >
            <div class="percentageBox">
              <el-progress
                :percentage="parameterConfigurationRuleGenerationPercentage"
                :show-text="false"
                :status="getPercentageStatus(parameterConfigurationRuleGenerationResult)"
              ></el-progress>

              <template v-if="parameterConfigurationRuleGenerationResult === 'fail'">
                <i class="el-icon-circle-close failResult" />
              </template>
              <i
                v-else-if="parameterConfigurationRuleGenerationResult === 'success'"
                class="el-icon-circle-check successResult"
              />
            </div>
          </el-form-item>
          <template v-for="item in picFormFields">
            <el-form-item
              v-show="item.chipType.includes(formData.chipType)"
              :key="item.prop"
              :label="item.label"
              :prop="item.prop"
            >
              <el-upload
                :ref="item.prop"
                action="#"
                :limit="1"
                :file-list="formData[item.prop]"
                list-type="picture-card"
                :accept="uploadSetting.pictureAccept"
                :http-request="(require) => handleUploadFiles(require, item.prop)"
                :disabled="formData[item.prop].length === uploadSetting.limit"
                :class="{ hide: isUpload(item.prop) || formData[item.prop].length === uploadSetting.limit }"
              >
                <i slot="default" class="el-icon-plus"></i>
                <div slot="file" slot-scope="{ file }">
                  <el-image
                    class="el-upload-list__item-thumbnail el-upload-list__item-img"
                    :src="file.base64"
                    :alt="file.name"
                  >
                    <div v-if="isUpload(item.prop)" slot="error" class="image-slot">
                      <i></i>
                    </div>
                  </el-image>
                  <span class="el-upload-list__item-actions">
                    <span class="el-upload-list__item-preview" @click="handlePreview(item.prop)">
                      <i class="el-icon-zoom-in"></i>
                    </span>
                    <span class="el-upload-list__item-delete" @click="handleRemove(item.prop)">
                      <i class="el-icon-delete"></i>
                    </span>
                  </span>
                </div>
              </el-upload>
            </el-form-item>
          </template>
        </el-form>
        <div class="drawerFooter" align="right">
          <el-button :loading="loading" @click="handleClose">取消</el-button>
          <el-button :loading="loading" :disabled="disabledBtn" type="primary" @click="handleSubmit">
            确认
          </el-button>
        </div>
      </div>
    </el-drawer>
    <el-dialog
      :title="'参数配置规则'"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
      :visible.sync="ruleDialogVisible"
      width="564px"
    >
      <el-table
        :height="500"
        :show-header="false"
        :data="parameterConfigurationRuleSetList"
        border
        style="width: 100%"
      >
        <el-table-column prop="ruleSetName" label="规则集名称">
          <template slot-scope="scope">{{ scope.row.ruleSetName }}规则集</template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="100" align="center">
          <template slot-scope="scope">
            <el-button type="text" size="small" @click="handleClick(scope.row)">查看</el-button>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleClose">关闭</el-button>
      </span>
    </el-dialog>
    <testResult ref="testResult" />
    <ruleSetDetail
      v-if="showRuleSetDetail"
      ref="ruleSetDetail"
      type="parameterConfigure"
      @close="showRuleSetDetail = false"
    />
  </div>
</template>

<script>
import { fileRuleCheck, initParameterConfiguration } from '@/api/rule-management'
import { uploadFile } from '@/api/system-management'
import { addChipByFile } from '@/api/project-management'
import { downLoadFileFromServer, fileDownload } from '@/utils/download'
import testResult from './testResult'
import ImagePreview from '@/components/preview'
import ruleSetDetail from '@/views/rule-management/components/ruleSetDetail.vue'
import defaultSettings from '@/settings'
import { generateUUID, postMessage, receivedMessage } from '@/utils/index'
export default {
  components: { testResult, ruleSetDetail },
  data() {
    return {
      drawerVisible: false,
      disabledBtn: false,
      loading: false,
      baseUrl: process.env.VUE_APP_BASE_API,
      uploadSetting: {
        limit: 1,
        url: process.env.VUE_APP_BASE_API + 'vue/files/upload',
        fileAccept: '.json',
        pictureAccept: '.jpg,.jpeg,.png' //, .m4v,.wmv,.asf,.asx,.rm,.rmvb,.mpg,.mpeg,.mpe,.3gp,.mov,.avi,.dat,.mkv,.flv,.vob
      },
      notPassDataList: [],
      ruleDialogVisible: false,
      rules: {
        chipType: [{ required: true, message: '请选择芯片类型', trigger: ['change', 'blur'] }],
        chipDefinitionFiles: [{ required: true, message: '请上传芯片定义文件', trigger: 'change' }]
      },
      formData: {
        chipDefinitionFiles: [],
        pinFiles: [],
        clockParameterFiles: [],
        performanceParameterFiles: []
      },
      picUpload: {
        pinFiles: { isupload: false },
        clockParameterFiles: { isupload: false }
      },
      picFormFields: [
        {
          label: '芯片引脚图',
          prop: 'pinFiles',
          chipType: [1, 2]
        },
        {
          label: '时钟配置图',
          prop: 'clockParameterFiles',
          chipType: [1]
        },
        {
          label: '主要性能参数图',
          prop: 'performanceParameterFiles',
          chipType: [2]
        }
      ],
      fileRulesCheckResult: 'running',

      fileRulesCheckPercentage: 0,
      startParameterConfigurationRuleGeneration: false,
      parameterConfigurationRuleGenerationResult: 'running',
      parameterConfigurationRuleGenerationPercentage: 0,
      parameterConfigurationRuleSetList: [],
      uploadFileRequestId: generateUUID(),
      currentUploadFile: {},
      addChipByFileRequestId: generateUUID(),
      getConditionalRelationOptionListRequestId: generateUUID(),
      fileRuleCheckRequestId: generateUUID(),
      initParameterConfigurationRequestId: generateUUID(),
      downloadFileRequestId: generateUUID(),
      timer: null,
      showRuleSetDetail: false
    }
  },
  created() {},
  mounted() {
    receivedMessage(this.dataHandle)
  },
  methods: {
    dataHandle(result) {
      let self = this
      let e = defaultSettings.isWPF ? result : { data: JSON.parse(result) }
      if (e.data.webInfo.requestId === self.uploadFileRequestId) {
        self.afterUpload(e.data.response)
      } else if (e.data.webInfo.requestId === self.addChipByFileRequestId) {
        self.afterAddChip(e.data.response)
      } else if (e.data.webInfo.requestId === self.fileRuleCheckRequestId) {
        let res = e.data.response
        self.disabledBtn = false
        if (res.success) {
          self.timer && clearInterval(self.timer)
          self.notPassDataList = res.data.notPassDataList
          if (self.notPassDataList.length === 0) {
            self.fileRulesCheckResult = 'success'
            self.fileRulesCheckPercentage = 100
          } else {
            self.fileRulesCheckResult = 'fail'
          }
        } else {
          self.notPassDataList = []
          self.timer && clearInterval(self.timer)
          self.fileRulesCheckResult = 'fail'
        }
      } else if (e.data.webInfo.requestId === self.initParameterConfigurationRequestId) {
        let res = e.data.response
        if (res.success) {
          self.$nextTick(() => {
            self.$refs.ruleSetDetail.is('view', res.data)
          })
        } else {
          self.$message.error(res.message)
        }
      } else if (e.data.webInfo.requestId === self.downloadFileRequestId) {
        let res = e.data.response
        if (res.success) {
          var bytes = new Uint8Array(
            window
              .atob(res.data)
              .split('')
              .map(function (c) {
                return c.charCodeAt(0)
              })
          )
          res.data = bytes
          fileDownload(res)
        } else {
          self.$message.error(res.message)
        }
      }
    },
    is(chipType) {
      this.startParameterConfigurationRuleGeneration = false
      this.drawerVisible = true
      this.disabledBtn = false
      this.fileRulesCheckResult = 'running'
      this.fileRulesCheckPercentage = 0
      this.parameterConfigurationRuleGenerationResult = 'running'
      this.parameterConfigurationRuleGenerationPercentage = 0
      this.loading = false
      this.formData = {
        chipType: chipType,
        chipDefinitionFiles: [],
        pinFiles: [],
        clockParameterFiles: [],
        performanceParameterFiles: []
      }
      this.$nextTick(() => {
        this.$refs.formData.clearValidate()
      })
    },
    isUpload(prop) {
      if (this.picUpload[prop] == undefined) {
        return false
      }
      return this.picUpload[prop].isupload
    },
    handleDownLoad() {
      if (this.formData.chipType) {
        const data = {}
        data.files = [
          {
            fileName: this.formData.chipType === 1 ? 'masterChip.json' : 'slaveChip.json',
            path:
              this.formData.chipType === 1
                ? 'uploads/files/chipTemplate/masterChip.json'
                : 'uploads/files/chipTemplate/slaveChip.json'
          }
        ]
        if (defaultSettings.isWPF || defaultSettings.isCEF) {
          this.downloadFileRequestId = generateUUID()
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/files/download',
            RequestMethod: 'POST',
            Headers: {
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: {
              files: data.files
            },
            WebInfo: {
              requestId: this.downloadFileRequestId
            }
          }
          postMessage(message)
        } else {
          downLoadFileFromServer(data).then((res) => {
            // console.log(res)
            if (res.data != null && res.data != '') {
              const text = JSON.stringify(res.data, null, 2)
              const blob = new Blob([text], { type: 'text/plain;charset=utf-8' })
              const url = window.URL.createObjectURL(blob)
              const a = document.createElement('a')
              a.href = url
              a.download = this.formData.chipType === 1 ? 'masterChip.json' : 'slaveChip.json'
              document.body.appendChild(a)
              a.click()
              document.body.removeChild(a)
              URL.revokeObjectURL(url)
            } else {
              this.$message.error('服务器找不到模板文件或文件内容异常,请询问管理员')
            }
          })
        }
      } else {
        this.$notify.warning('请选择芯片类型')
      }
    },
    // 查看检查结果
    handleView() {
      this.$refs.testResult.is({
        chipDefinitionFiles: this.formData.chipDefinitionFiles,
        notPassDataList: this.notPassDataList
      })
    },
    handleExceed(files) {
      this.$refs.chipDefinitionFiles.clearFiles()
      this.handleUploadFiles({ file: files[0] }, 'chipDefinitionFiles')
    },
    // 上传前校验
    handleCheck(params, fileName) {
      var suffix = params.file.name.substring(params.file.name.lastIndexOf('.')) // .txt
      const isLimit = params.file.size / 1024 / 1024 < 20
      var accept =
        this.uploadSetting[fileName === 'chipDefinitionFiles' ? 'fileAccept' : 'pictureAccept'].split(',')
      if (accept.includes(suffix)) {
        if (!isLimit) {
          this.$notify.error('上传文件大小不能超过 20MB!')
          return false
        } else {
          return true
        }
      } else {
        this.$notify.error('上传附件不符合上传格式!')
        return false
      }
    },
    // 图片上传
    handleUploadFiles(require, fileName) {
      let fileDom
      if (fileName === 'chipDefinitionFiles') {
        this.disabledBtn = true
        fileDom = this.$refs[fileName].uploadFiles
        this.fileRulesCheckPercentage = 10
        this.fileRulesCheckResult = 'running'
        this.parameterConfigurationRuleGenerationPercentage = 0
        this.parameterConfigurationRuleGenerationResult = 'running'
      } else {
        fileDom = this.$refs[fileName][0].uploadFiles
      }
      let uploadFilesLast = fileDom.length - 1
      let check = this.handleCheck(require, fileName)
      if (!check) {
        fileDom.splice(uploadFilesLast, 1)
        return
      }
      this.currentUploadFile = { require, fileName }

      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        let self = this
        this.uploadFileRequestId = generateUUID()
        let reader = new FileReader() // new一个FileReader实例
        reader.readAsDataURL(require.file)
        if (fileName !== 'chipDefinitionFiles') {
          this.picUpload[this.currentUploadFile.fileName].isupload = true
        }
        reader.onload = function () {
          //   读取文件获得的对象
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/files/upload',
            RequestMethod: 'POST',
            Headers: {
              // contentType: fileName === 'chipDefinitionFiles' ? 'multipart/form-data' : 'application/json',
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: {
              fileName: require.file.name,
              fileContent: reader.result.split(',')[1]
            },
            WebInfo: {
              requestId: self.uploadFileRequestId
            }
          }
          postMessage(message)
        }
      } else {
        if (fileName !== 'chipDefinitionFiles') {
          this.picUpload[this.currentUploadFile.fileName].isupload = true
        }
        let formData = new FormData()
        formData.append('file', require.file)
        uploadFile(formData)
          .then((res) => {
            this.afterUpload(res)
          })
          .catch(() => {
            fileDom.splice(uploadFilesLast, 1)
            if (fileName !== 'chipDefinitionFiles') {
              this.picUpload[this.currentUploadFile.fileName].isupload = true
            }
            this.$notify.error('上传失败')
          })
      }
    },
    afterUpload(res) {
      this.formData[this.currentUploadFile.fileName] = [
        {
          uid: this.currentUploadFile.require.file.uid,
          fileType: res.data.fileType,
          name: res.data.name,
          fileName: res.data.name,
          url: res.data.url,
          path: res.data.url,
          base64: 'data:image/png;base64,' + res.data.base64
        }
      ]
      this.$refs.formData.validateField(this.currentUploadFile.fileName)
      if (this.currentUploadFile.fileName === 'chipDefinitionFiles') {
        this.notPassDataList = []

        this.timer = setInterval(() => {
          this.fileRulesCheckPercentage += 10
          if (this.fileRulesCheckPercentage === 90) {
            this.timer && clearInterval(this.timer)
          }
        }, 50)
        if (defaultSettings.isWPF || defaultSettings.isCEF) {
          this.fileRuleCheckRequestId = generateUUID()
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/chip/fileRuleCheck',
            RequestMethod: 'POST',
            Headers: {
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: {
              filePath: res.data.url,
              ruleSetType: this.formData.chipType
            },
            WebInfo: {
              requestId: this.fileRuleCheckRequestId
            }
          }
          postMessage(message)
        } else {
          fileRuleCheck({
            filePath: res.data.url,
            ruleSetType: this.formData.chipType
          })
            .then((res) => {
              this.timer && clearInterval(this.timer)
              this.notPassDataList = res.data.notPassDataList
              if (this.notPassDataList.length === 0) {
                this.fileRulesCheckResult = 'success'
                this.fileRulesCheckPercentage = 100
              } else {
                this.fileRulesCheckResult = 'fail'
              }
            })
            .catch(() => {
              this.notPassDataList = []
              this.timer && clearInterval(this.timer)
              this.fileRulesCheckResult = 'fail'
            })
            .finally(() => {
              this.disabledBtn = false
            })
        }
      }
    },
    getPercentageStatus(status) {
      let result = ''
      switch (status) {
        case 'success':
          result = 'success'
          break
        case 'fail':
          result = 'exception'
          break
        default:
          result = undefined
      }
      return result
    },
    handleRemove(fileName) {
      if (fileName === 'chipDefinitionFiles') {
        this.fileRulesCheckPercentage = 0
        this.fileRulesCheckResult = 'running'
        this.parameterConfigurationRuleGenerationPercentage = 0
        this.parameterConfigurationRuleGenerationResult = 'running'
      } else {
        this.picUpload[fileName].isupload = false
        this.formData[fileName] = []
      }
    },
    handlePreview(fileName) {
      ImagePreview(this.formData[fileName], 0)
    },
    handleClose() {
      this.$refs.chipDefinitionFiles.clearFiles()
      this.picFormFields.forEach((item) => {
        this.$refs?.[item.prop]?.[0]?.clearFiles()
      })
      this.drawerVisible = false
      this.ruleDialogVisible = false
    },
    handleClick(row) {
      this.showRuleSetDetail = true
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.initParameterConfigurationRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/ruleSet/initParameterConfiguration',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: { ruleSetId: row.ruleSetId },
          WebInfo: {
            requestId: this.initParameterConfigurationRequestId
          }
        }
        postMessage(message)
      } else {
        initParameterConfiguration({ ruleSetId: row.ruleSetId }).then((res) => {
          this.$nextTick(() => {
            this.$refs.ruleSetDetail.is('view', res.data)
          })
        })
      }
    },
    handleSubmit() {
      if (this.fileRulesCheckResult === 'fail') {
        this.$notify.error('芯片定义文件未通过文件规则检查')
        return
      }
      this.$refs.formData.validate((valid) => {
        if (valid) {
          this.startParameterConfigurationRuleGeneration = true
          this.loading = true
          let params = {
            chipType: this.formData.chipType,
            chipDefinitionFiles: this.formData.chipDefinitionFiles.map((item) => {
              return { ...item, base64: '' }
            }),
            pinFiles: this.formData.pinFiles.map((item) => {
              return { ...item, base64: '' }
            }),
            clockParameterFiles:
              this.formData.chipType === 1
                ? this.formData.clockParameterFiles.map((item) => {
                    return { ...item, base64: '' }
                  })
                : [],
            performanceParameterFiles:
              this.formData.chipType === 2
                ? this.formData.performanceParameterFiles.map((item) => {
                    return { ...item, base64: '' }
                  })
                : []
          }
          if (this.formData.chipType === 1) {
            this.timer = setInterval(() => {
              this.parameterConfigurationRuleGenerationPercentage += 10
              if (this.parameterConfigurationRuleGenerationPercentage === 90) {
                this.timer && clearInterval(this.timer)
              }
            }, 200)
          }

          if (defaultSettings.isWPF || defaultSettings.isCEF) {
            this.addChipByFileRequestId = generateUUID()
            let message = {
              RequestUrl: process.env.VUE_APP_URL + '/chip/addChipByFile',
              RequestMethod: 'POST',
              Headers: {
                contentType: 'application/json'
              },
              QueryParameter: {},
              RequestBody: params,
              WebInfo: {
                requestId: this.addChipByFileRequestId
              }
            }
            postMessage(message)
          } else {
            addChipByFile(params)
              .then((res) => {
                this.afterAddChip(res)
              })
              .catch(() => {
                if (this.formData.chipType === 1) {
                  this.timer && clearInterval(this.timer)
                  this.parameterConfigurationRuleGenerationResult = 'fail'
                }
                this.loading = false
              })
          }
        }
      })
    },
    afterAddChip(res) {
      this.formData.chipType === 1 && this.timer && clearInterval(this.timer)
      this.loading = false
      if (res.success) {
        this.$notify.success('添加芯片成功')
        this.$emit('refresh', this.formData.chipType)
        if (this.formData.chipType === 1) {
          this.ruleDialogVisible = true
          this.parameterConfigurationRuleSetList = res.data
          this.parameterConfigurationRuleGenerationResult = 'success'
          this.parameterConfigurationRuleGenerationPercentage = 100
        } else {
          this.handleClose()
        }
      } else {
        this.formData.chipType === 1 && (this.parameterConfigurationRuleGenerationResult = 'fail')
        this.$notify.error(res.message)
      }
    }
  }
}
</script>

<style lang="less" scoped>
.el-upload-list__item-img {
  width: 146px;
  height: 146px;
}
.hide {
  /deep/.el-upload--picture-card {
    display: none !important;
  }
}
.addChipContent {
  .drawerForm {
    display: flex;
    flex-direction: column;
    height: 100%;
    .pageTitle {
      padding: 15px;
      font-size: 16px;
      color: #333;
      font-weight: bold;
      .titleText {
        display: inline;
        padding-right: 20px;
        padding-left: 5px;
      }
    }
    .myForm {
      height: calc(100% - 100px);
      margin: 0px 20px;
      display: flex;
      flex-direction: column;
      overflow-y: auto;
      padding-right: 7px;
    }
    .drawerFooter {
      padding: 0 20px;
      float: right;
    }
  }
}

.percentageBox {
  height: 32px;
  display: flex;
  padding-right: 5px;
  align-items: center;
  .el-progress {
    flex: 1;
    padding-right: 10px;
  }
  .successResult {
    color: #67c23a;
  }
  .failResult {
    color: #f56c6c;
  }
  .downloadBtn {
    margin-left: 10px;
    // padding-right: 0;
  }
}
</style>
